import tkinter as tk
from tkinter import messagebox
import json
import re
import os

class CodeEditor:
    def __init__(self, root):
        self.root = root
        self.root.title("高亮代码编辑器")

        self.config_path = "language_config.json"

        # 创建文本编辑区
        self.text_area = tk.Text(root, wrap=tk.WORD, font=("Courier New", 12))
        self.text_area.pack(fill=tk.BOTH, expand=True)

        self.config = self.load_language_config()

        # 设置高亮样式
        for i in self.config["highlights config"]:
            self.text_area.tag_config(i, foreground=self.config["highlights config"][i]["color"], font=self.config["highlights config"][i]["font"])
            print(f"self.text_area.tag_config({i}, foreground={self.config['highlights config'][i]['color']}, font={self.config['highlights config'][i]['font']}")

        # 绑定修改事件进行高亮
        self.text_area.bind("<<Modified>>", self.on_modified)

    def load_language_config(self):
        """加载语言配置文件"""
        if not os.path.exists(self.config_path):
            messagebox.showerror("错误", "找不到语言配置文件 'language_config.json'")
            return {}

        try:
            with open(self.config_path, "r", encoding="utf-8") as f:
                return json.load(f)

        except Exception as e:
            messagebox.showerror("错误", f"加载语言配置文件出错: {str(e)}")
            return {}

    def load_file(self, file_path):
        """加载文件到编辑器"""
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                content = f.read()
                self.text_area.delete(1.0, tk.END)
                self.text_area.insert(tk.END, content)
                self.text_area.edit_modified(True)
                return True
        except Exception as e:
            messagebox.showerror("错误", f"加载文件出错: {str(e)}")
            return False

    def apply_highlights(self):
        """应用关键字高亮"""
        # 清除所有高亮
        for tag in self.text_area.tag_names():
            self.text_area.tag_remove(tag, "1.0", tk.END)

        # 获取文本内容
        content = self.text_area.get("1.0", tk.END)

        # 获取当前文件类型（根据文件扩展名判断）
        file_path = "demo.py"  # 目前固定为demo.py
        file_ext = os.path.splitext(file_path)[1][1:].lower()

        if file_ext in self.config["language"]:
            lang_config = self.config["language"][file_ext]
            keywords = lang_config["built-in"].get("keywords", [])
            functions = lang_config["built-in"].get("functions", [])
            regex = lang_config.get("regex", [])

            # 应用 关键字 高亮
            for keyword in keywords:
                start = "1.0"
                while True:
                    start = self.text_area.search(rf"\m{re.escape(keyword)}\M", start, stopindex=tk.END, regexp=True)
                    if not start:
                        break
                    end = self.text_area.index(f"{start}+{len(keyword)}c")
                    self.text_area.tag_add("keyword", start, end)
                    start = end

            # 应用 内置函数 高亮
            for function in functions:
                start = "1.0"
                while True:
                    start = self.text_area.search(rf"\m{re.escape(function)}\M", start, stopindex=tk.END,
                                                  regexp=True)
                    if not start:
                        break
                    end = self.text_area.index(f"{start}+{len(function)}c")
                    self.text_area.tag_add("function", start, end)
                    start = end

            # 应用 正则表达式 高亮
            for pattern in regex:
                matches = re.finditer(pattern["pattern"], content)
                for match in matches:
                    start_pos = match.start()
                    end_pos = match.end()

                    # 将字符位置转换为文本区域的索引
                    char_count = 0
                    line_number = 1
                    col_number = 0

                    for i, char in enumerate(content[:start_pos]):
                        if char == '\n':
                            line_number += 1
                            col_number = 0
                        else:
                            col_number += 1

                    start = f"{line_number}.{col_number}"
                    end_pos_in_line = min(end_pos - start_pos, len(content[start_pos:end_pos]) - col_number)
                    end = f"{line_number}.{col_number + (end_pos - start_pos)}"

                    self.text_area.tag_add(pattern["tag"], start, end)
        else:
            print(f"没有配置 {file_ext} 语言的高亮规则")

    def on_modified(self, event):
        """文本修改事件处理"""
        # 忽略事件本身的修改标记
        self.text_area.edit_modified(False)

        # 应用高亮
        self.apply_highlights()

def main():
    root = tk.Tk()
    editor = CodeEditor(root)

    # 加载demo.py文件
    if editor.load_file("demo.py"):
        # 初始应用高亮
        editor.apply_highlights()

    root.mainloop()


if __name__ == "__main__":
    main()